Passed
Push — feature/share-pages ( ea9437...96d3f9 )
by Kevin Van
04:40 queued 49s
created

PlayerShare   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 35
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 8
eloc 30
dl 0
loc 35
rs 10
c 0
b 0
f 0

1 Function

Rating   Name   Duplication   Size   Complexity  
B render 0 33 8
1
import React, { Component, Fragment } from "react"
2
import { graphql, StaticQuery } from "gatsby"
3
import { mapPositionCode } from "../scripts/helper"
4
import { getSrc } from "gatsby-plugin-image"
5
import { useQueryParam, StringParam } from "use-query-params"
6
7
import moment from "moment"
8
9
import "./player.scss"
10
import { Link } from "gatsby"
11
import Helmet from "react-helmet"
12
13
import Icon from "../components/Icon"
14
import RelatedNews from "../components/RelatedNews"
15
16
import iconCleansheet from "../images/i_cleansheet.png"
17
import iconCardRed from "../images/i_card_red.png"
18
import iconCardYellow from "../images/i_card_yellow.png"
19
import iconGoal from "../images/i_goal.png"
20
import Card from "./Card"
21
22
// eslint-disable-next-line
23
String.prototype.replaceAll = function (search, replacement) {
24
  var target = this
25
  return target.replace(new RegExp(search, `g`), replacement)
26
}
27
28
class Player extends Component {
29
  render() {
30
    const { player, config } = this.props
31
    const [view, setView] = useQueryParam(`view`, StringParam)
32
33
    if (view === `share`) {
34
      return <PlayerShare player={player} />
35
    }
36
    return <PlayerDetail player={player} config={config} />
37
  }
38
}
39
40
class PlayerShare extends Component {
41
  render() {
42
    const { player } = this.props
43
    const [score] = useQueryParam(`score`, StringParam)
44
    const [match] = useQueryParam(`match`, StringParam)
45
    const [assist] = useQueryParam(`assist`, StringParam)
46
47
    const fallback =
48
      player.relationships?.field_image?.localFile?.childImageSharp?.gatsbyImageData?.placeholder?.fallback || null
49
    const image = getSrc(player.relationships.field_image?.localFile.childImageSharp.gatsbyImageData) || null
50
51
    return (
52
      <article className={`player-detail`}>
53
        <Helmet
54
          bodyAttributes={{
55
            class: `share`,
56
          }}
57
        />
58
        <div>
59
          <img src={fallback} />
60
          <div
61
            className={`player-detail__bg-avatar`}
62
            style={
63
              player.relationships.field_image && {
64
                backgroundImage: `url(${image})`,
65
              }
66
            }
67
          />
68
          <p>{score}</p>
69
          <p>{match}</p>
70
          <p>{assist}</p>
71
          {console.log(player.relationships.field_image.localFile.childImageSharp.gatsbyImageData.placeholder.fallback)}
72
        </div>
73
      </article>
74
    )
75
  }
76
}
77
78
/**
79
 */
80
class PlayerDetail extends Component {
81
  constructor(props) {
82
    super(props)
83
84
    this.state = {
85
      data: [],
86
      loading: true,
87
    }
88
89
    const {
90
      config: {
91
        site: {
92
          siteMetadata: { kcvvPsdApi },
93
        },
94
      },
95
      player: { field_vv_id: playerId },
96
    } = this.props
97
98
    this.kcvvPsdApi = kcvvPsdApi
99
    this.playerId = playerId
100
  }
101
102
  updateData() {
103
    if (this.playerId === null) {
104
      return
105
    }
106
107
    const apiUrl = `${this.kcvvPsdApi}/stats/player/${this.playerId}`
108
109
    fetch(apiUrl)
110
      .then((response) => response.json())
111
      .then((json) => this.setState({ data: json, loading: false }))
112
      .catch(() => this.setState({ data: {}, loading: false }))
113
  }
114
115
  componentDidMount() {
116
    this.updateData()
117
  }
118
119
  renderPlayerName = (player) => (
120
    <h1 className={`player-detail__name`}>
121
      <span className={`player-detail__name-first`}>{player.field_firstname}</span>
122
      <span className={`player-detail__name-last`}>{player.field_lastname}</span>
123
    </h1>
124
  )
125
  renderPlayerImage = (player) => (
126
    <div className={`bg-green-mask`}>
127
      <div
128
        className={`player-detail__bg-avatar`}
129
        style={
130
          player.relationships.field_image && {
131
            backgroundImage: `url(${getSrc(
132
              player.relationships.field_image.localFile.childImageSharp.gatsbyImageData
133
            )})`,
134
          }
135
        }
136
      />
137
      <div className={`bg-white-end`} />
138
    </div>
139
  )
140
  renderPlayerHeader = (player) => (
141
    <header className={`player-detail__header`}>
142
      {this.renderPlayerName(player)}
143
      {this.renderPlayerImage(player)}
144
145
      <div className={`player-detail__bg-shirt-number`} aria-hidden="true">
146
        {player.field_shirtnumber || ``}
147
      </div>
148
    </header>
149
  )
150
  renderPlayerStats = (player) => {
151
    if (this.state.loading === false && this.state.data) {
152
      const { playerStatistics = [] } = this.state.data
153
154
      return (
155
        <aside className={`player-detail__statistics`}>
156
          <section className={`player-detail__statistics-item`}>
157
            <div className={`player-detail__statistics-item__number`}>
158
              {playerStatistics.reduce((a, b) => a + (b?.gamesPlayed || 0), 0) || `0`}
159
            </div>
160
            <div className={`player-detail__statistics-item__label`}>Wedstrijden</div>
161
          </section>
162
163
          {(player.field_position === `k` || player.field_position === `d`) && (
164
            <section className={`player-detail__statistics-item`}>
165
              <div className={`player-detail__statistics-item__number`}>
166
                {playerStatistics.reduce((a, b) => a + (b?.cleanSheets || 0), 0) || `0`}
167
              </div>
168
              <div className={`player-detail__statistics-item__label`}>Cleansheets</div>
169
            </section>
170
          )}
171
          {player.field_position !== `k` && (
172
            <section className={`player-detail__statistics-item`}>
173
              <div className={`player-detail__statistics-item__number`}>
174
                {playerStatistics.reduce((a, b) => a + (b?.goals || 0), 0) || `0`}
175
              </div>
176
              <div className={`player-detail__statistics-item__label`}>Doelpunten</div>
177
            </section>
178
          )}
179
          <section className={`player-detail__statistics-item`}>
180
            <div className={`player-detail__statistics-item__number`}>
181
              {playerStatistics.reduce((a, b) => a + (b?.yellowCards || 0), 0) || `0`}
182
            </div>
183
            <div className={`player-detail__statistics-item__label`}>Gele kaarten</div>
184
          </section>
185
          <section className={`player-detail__statistics-item`}>
186
            <div className={`player-detail__statistics-item__number`}>
187
              {playerStatistics.reduce((a, b) => a + (b?.redCards || 0), 0) || `0`}
188
            </div>
189
            <div className={`player-detail__statistics-item__label`}>Rode kaarten</div>
190
          </section>
191
        </aside>
192
      )
193
    }
194
  }
195
196
  renderPlayerStatsFull = (player) => {
197
    if (this.state.loading === false && this.state.data) {
198
      const { playerStatistics = [] } = this.state.data
199
200
      return (
201
        <Card title="Statistieken" className={`player-detail__stats`} hasTable={true}>
202
          <table className={`player-detail__stats__table`}>
203
            <thead>
204
              <tr>
205
                <th className={`player-detail__column player-detail__column--string`}>Team</th>
206
                <th className={`player-detail__column player-detail__column--number show-for-medium`}>
207
                  <span title="Wedstrijden gespeeld">P</span>
208
                </th>
209
                <th className={`player-detail__column player-detail__column--number`}>
210
                  <span title="Wedstrijden gewonnen">W</span>
211
                </th>
212
                <th className={`player-detail__column player-detail__column--number`}>
213
                  <span title="Wedstrijden gelijkgespeeld">D</span>
214
                </th>
215
                <th className={`player-detail__column player-detail__column--number`}>
216
                  <span title="Wedstrijden verloren">L</span>
217
                </th>
218
                <th className={`player-detail__column player-detail__column--number`}>
219
                  <img
220
                    src={iconCardYellow}
221
                    title="Gele kaart"
222
                    alt="Gele kaart"
223
                    className="player-detail__stats--header_icon"
224
                  />
225
                </th>
226
                <th className={`player-detail__column player-detail__column--number`}>
227
                  <img
228
                    src={iconCardRed}
229
                    title="Rode kaart"
230
                    alt="Rode kaart"
231
                    className="player-detail__stats--header_icon"
232
                  />
233
                </th>
234
                <th className={`player-detail__column player-detail__column--number`}>
235
                  <img
236
                    src={iconGoal}
237
                    title="Doelpunt(en) gescoord"
238
                    alt="Doelpunt(en) gescoord"
239
                    className="player-detail__stats--header_icon"
240
                  />
241
                </th>
242
                <th className={`player-detail__column player-detail__column--number  show-for-medium`}>
243
                  <img
244
                    src={iconCleansheet}
245
                    title="Cleansheets"
246
                    alt="Cleansheets"
247
                    className="player-detail__stats--header_icon"
248
                  />
249
                </th>
250
                <th className={`player-detail__column player-detail__column--number`}>
251
                  <span title="Minuten gespeeld">
252
                    <Icon icon="fa-clock-o" />
253
                  </span>
254
                </th>
255
              </tr>
256
            </thead>
257
            <tbody>
258
              {playerStatistics.map(function (stats) {
259
                return (
260
                  <tr>
261
                    <td className={`player-detail__column player-detail__column--string`}>
262
                      {stats.team.replace(`Voetbal : `, ``)}
263
                    </td>
264
                    <td className={`player-detail__column player-detail__column--number show-for-medium`}>
265
                      {stats.gamesPlayed}
266
                    </td>
267
                    <td className={`player-detail__column player-detail__column--number`}>{stats.gamesWon}</td>
268
                    <td className={`player-detail__column player-detail__column--number`}>{stats.gamesEqual}</td>
269
                    <td className={`player-detail__column player-detail__column--number`}>{stats.gamesLost}</td>
270
                    <td className={`player-detail__column player-detail__column--number`}>{stats.yellowCards}</td>
271
                    <td className={`player-detail__column player-detail__column--number`}>{stats.redCards}</td>
272
                    <td className={`player-detail__column player-detail__column--number`}>{stats.goals}</td>
273
                    <td className={`player-detail__column player-detail__column--number show-for-medium`}>
274
                      {stats.cleanSheets}
275
                    </td>
276
                    <td className={`player-detail__column player-detail__column--number`}>{stats.minutes}'</td>
277
                  </tr>
278
                )
279
              })}
280
            </tbody>
281
          </table>
282
        </Card>
283
      )
284
    }
285
  }
286
  renderPlayerGamesFull = () => {
287
    if (this.state.loading === false && this.state.data) {
288
      const { gameReports = [] } = this.state.data
289
290
      return (
291
        <Card className={`player-detail__games`} title="Wedstrijden" hasTable={true}>
292
          <table className={`player-detail__games__table responsive-card-table`}>
293
            <thead>
294
              <tr>
295
                <th className={`player-detail__column player-detail__column--string`}>Team</th>
296
                <th className={`player-detail__column player-detail__column--string`}>Type</th>
297
                <th className={`player-detail__column player-detail__column--string`}>Datum</th>
298
                <th className={`player-detail__column player-detail__column--number`}>
299
                  <span title="Thuis/uit">H/A</span>
300
                </th>
301
                <th className={`player-detail__column player-detail__column--score`}>Score</th>
302
                <th className={`player-detail__column player-detail__column--string`}>Tegenstander</th>
303
                <th className={`player-detail__column player-detail__column--number`}>
304
                  <img
305
                    src={iconCardYellow}
306
                    title="Gele kaart"
307
                    alt="Gele kaart"
308
                    className="player-detail__stats--header_icon"
309
                  />
310
                </th>
311
                <th className={`player-detail__column player-detail__column--number`}>
312
                  <img
313
                    src={iconCardRed}
314
                    title="Rode kaart"
315
                    alt="Rode kaart"
316
                    className="player-detail__stats--header_icon"
317
                  />
318
                </th>
319
                <th className={`player-detail__column player-detail__column--number`}>
320
                  <img
321
                    src={iconGoal}
322
                    title="Doelpunten gescoord"
323
                    alt="Rode kaart"
324
                    className="player-detail__stats--header_icon"
325
                  />
326
                </th>
327
                <th className={`player-detail__column player-detail__column--number`}>
328
                  <span title="Minuten gespeeld">
329
                    <Icon icon="fa-clock-o" />
330
                  </span>
331
                </th>
332
              </tr>
333
            </thead>
334
            <tbody>
335
              {gameReports.map(function (game) {
336
                return (
337
                  <tr>
338
                    <td data-label="Team" className={`player-detail__column player-detail__column--string`}>
339
                      {game.team.replace(`Voetbal : `, ``)}
340
                    </td>
341
                    <td data-label="Type" className={`player-detail__column player-detail__column--string`}>
342
                      {game.competition}
343
                    </td>
344
                    <td data-label="Datum" className={`player-detail__column player-detail__column--string`}>
345
                      {moment(game.date).format(`DD/MM/YYYY`)}
346
                    </td>
347
                    <td data-label="Thuis/uit" className={`player-detail__column player-detail__column--number`}>
348
                      {game.home ? (
349
                        <span className={`player-detail__games__home`} title="Thuiswedstrijd">
350
                          <Icon icon="fa-home" alt="Thuiswedstrijd" />
351
                        </span>
352
                      ) : (
353
                        <span className={`player-detail__games__away`} title="Uitwedstrijd">
354
                          <Icon icon="fa-bus" alt="Uitwedstrijd" />
355
                        </span>
356
                      )}
357
                    </td>
358
                    <td data-label="Score" className={`player-detail__column player-detail__column--score`}>
359
                      {game.goalsHomeTeam}&nbsp;-&nbsp;{game.goalsAwayTeam}
360
                    </td>
361
                    <td data-label="Tegenstander" className={`player-detail__column player-detail__column--string`}>
362
                      {game.opponent}
363
                    </td>
364
                    <td data-label="Gele kaart(en)" className={`player-detail__column player-detail__column--number`}>
365
                      {game.yellowCards}
366
                    </td>
367
                    <td data-label="Rode kaart(en)" className={`player-detail__column player-detail__column--number`}>
368
                      {game.redCards}
369
                    </td>
370
                    <td data-label="Doelpunten" className={`player-detail__column player-detail__column--number`}>
371
                      {game.goals}
372
                    </td>
373
                    <td data-label="Speeltijd" className={`player-detail__column player-detail__column--number`}>
374
                      {game.minutesPlayed}'
375
                    </td>
376
                  </tr>
377
                )
378
              })}
379
            </tbody>
380
          </table>
381
        </Card>
382
      )
383
    }
384
  }
385
386
  renderPlayerBirthdate = (player) => (
387
    <div className={`player-detail__data-item player-detail__data-item--birthdate`}>
388
      <span className={`player-detail__data-item__label`}>Geboortedatum</span>
389
      <span className={`player-detail__data-item__data`}>{player.field_birth_date || `Onbekend`}</span>
390
    </div>
391
  )
392
  renderPlayerPosition = (player) => (
393
    <div className={`player-detail__data-item player-detail__data-item--position`}>
394
      <span className={`player-detail__date-item__data`}>
395
        {player.field_position && mapPositionCode(player.field_position)}
396
      </span>
397
      <span className={`player-detail__data-item__label`}>
398
        {player.relationships.node__team && (
399
          <Link to={player.relationships.node__team[0].path.alias}>{player.relationships.node__team[0].title}</Link>
400
        )}
401
      </span>
402
    </div>
403
  )
404
  renderPlayerJoinDate = (player) => {
405
    const currentlyPlaying = !player.field_date_leave
406
    return (
407
      <div className={`player-detail__data-item player-detail__data-item--joindate`}>
408
        <span className={`player-detail__data-item__label`}>
409
          {currentlyPlaying && `Speler bij KCVV sinds`}
410
          {!currentlyPlaying && `Speler tussen`}
411
        </span>
412
        <span className={`player-detail__data-item__data`}>
413
          {player.field_join_date || `Onbekend`}
414
          {!currentlyPlaying && (
415
            <Fragment>
416
              <span className={`text--regular`}> en </span> {player.field_date_leave}
417
            </Fragment>
418
          )}
419
        </span>
420
      </div>
421
    )
422
  }
423
  renderPlayerData = (player) => (
424
    <section className={`player-detail__data`}>
425
      {this.renderPlayerBirthdate(player)}
426
      {this.renderPlayerPosition(player)}
427
      {this.renderPlayerJoinDate(player)}
428
    </section>
429
  )
430
  renderPlayerBody = (player) => {
431
    const cleanBody =
432
      (player.body &&
433
        player.body.processed.replaceAll(`/sites/default/`, `${process.env.GATSBY_API_DOMAIN}/sites/default/`)) ||
434
      ``
435
436
    return (
437
      <section className={`player-detail__body`}>
438
        <div dangerouslySetInnerHTML={{ __html: cleanBody }} />
439
      </section>
440
    )
441
  }
442
  render() {
443
    const { player } = this.props
444
445
    const team = player.relationships.node__team || []
446
    const articles = player.relationships.node__article || []
447
448
    return (
449
      <>
450
        <article className={`player-detail`}>
451
          {this.renderPlayerHeader(player)}
452
          {this.renderPlayerStats(player)}
453
          <div className={`player-break`}></div>
454
          {this.renderPlayerData(player)}
455
          {this.renderPlayerBody(player)}
456
          {this.renderPlayerStatsFull(player)}
457
          {this.renderPlayerGamesFull(player)}
458
459
          <div>
460
            {console.log(
461
              player.relationships.field_image.localFile.childImageSharp.gatsbyImageData.placeholder.fallback
462
            )}
463
          </div>
464
        </article>
465
466
        {(team || articles) && <RelatedNews items={team.concat(articles)} limit={6} />}
467
      </>
468
    )
469
  }
470
}
471
472
// Retrieve endpoint of the logo's api from the site metadata (gatsby-config.js).
473
const query = graphql`
474
  query {
475
    site {
476
      siteMetadata {
477
        kcvvPsdApi
478
      }
479
    }
480
  }
481
`
482
483
export default ({ player }) => (
484
  <StaticQuery
485
    query={query}
486
    render={(data) => (
487
      <Player
488
        // Data is the result of our query.
489
        config={data}
490
        player={player}
491
      />
492
    )}
493
  />
494
)
495